package org.spider.config;

import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.spider.model.dto.SpiderUser;
import org.springblade.core.launch.constant.TokenConstant;
import org.springblade.core.secure.utils.SecureUtil;
import org.springblade.core.tool.utils.Charsets;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.WebUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Base64;

@Component
@Slf4j
public class TokenArgumentInterceptor implements HandlerInterceptor {

    private static final String BLADE_USER_REQUEST_ATTR = "_BLADE_USER_REQUEST_ATTR_";

    private final static String HEADER = TokenConstant.HEADER;
    private final static String BEARER = TokenConstant.BEARER;
    private final static String ACCOUNT = TokenConstant.ACCOUNT;
    private final static String USER_ID = TokenConstant.USER_ID;
    private final static String ROLE_ID = TokenConstant.ROLE_ID;
    private final static String DEPT_ID = TokenConstant.DEPT_ID;
    private final static String USER_NAME = TokenConstant.USER_NAME;
    private final static String ROLE_NAME = TokenConstant.ROLE_NAME;
    private final static String TENANT_ID = TokenConstant.TENANT_ID;
    private final static String CLIENT_ID = TokenConstant.CLIENT_ID;
    private final static Integer AUTH_LENGTH = TokenConstant.AUTH_LENGTH;
    private static final String BASE64_SECURITY = Base64.getEncoder().encodeToString(TokenConstant.SIGN_KEY.getBytes(Charsets.UTF_8));

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 优先从 request 中获取
        Object spiderUser = request.getAttribute(BLADE_USER_REQUEST_ATTR);
        if (spiderUser == null) {
            spiderUser = getUser(request);
            if (spiderUser != null) {
                // 设置到 request 中
                request.setAttribute(BLADE_USER_REQUEST_ATTR, spiderUser);
            }
        }
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    public static SpiderUser getUser(HttpServletRequest request) {
        Claims claims = getClaims(request);
        if (claims == null) {
            return null;
        }
        String clientId = Func.toStr(claims.get(CLIENT_ID));
        Long userId = Func.toLong(claims.get(USER_ID));
        String tenantId = Func.toStr(claims.get(TENANT_ID));
        String roleId = Func.toStr(claims.get(ROLE_ID));
        String deptId = Func.toStr(claims.get(DEPT_ID));
        String account = Func.toStr(claims.get(ACCOUNT));
        String roleName = Func.toStr(claims.get(ROLE_NAME));
        String userName = Func.toStr(claims.get(USER_NAME));
        SpiderUser spiderUser = new SpiderUser();
        spiderUser.setClientId(clientId);
        spiderUser.setUserId(userId);
        spiderUser.setTenantId(tenantId);
        spiderUser.setAccount(account);
        spiderUser.setRoleId(roleId);
        spiderUser.setDeptId(deptId);
        spiderUser.setRoleName(roleName);
        spiderUser.setUserName(userName);
        return spiderUser;
    }

    public static Claims getClaims(HttpServletRequest request) {
        String auth = request.getHeader(HEADER);
        if (StringUtils.isNotBlank(auth) && auth.length() > AUTH_LENGTH) {
            String headStr = auth.substring(0, 6).toLowerCase();
            if (headStr.compareTo(BEARER) == 0) {
                auth = auth.substring(7);
                return SecureUtil.parseJWT(auth);
            }
        } else {
            String parameter = request.getParameter(HEADER);
            if (StringUtils.isNotBlank(parameter)) {
                return SecureUtil.parseJWT(parameter);
            }
        }
        return null;
    }
}
